home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
pcmagazi
/
1986
/
07
/
rendir.asm
next >
Wrap
Assembly Source File
|
1986-01-23
|
10KB
|
245 lines
RENDIR segment para public 'code'
assume cs:RENDIR, ds:RENDIR, es:RENDIR, ss:NOTHING
org 100h ; .COM format
BEGIN:
jmp CODE_START ; Jump around data declarations
DECLARE: ; Equates and Storage allocation for messages & data areas
COPYRIGHT db 'RENDIR (C) 1986, Ziff-Davis Publishing Co.'
db 13,10,'$'
PATH_FILE_LEN equ 77 ;Length = 1, Path = 63, FileName = 12, 0 = 1
SOURCE_NAME db PATH_FILE_LEN dup (0)
TARGET_NAME db PATH_FILE_LEN dup (0)
TARGET_END dw $ - 1
VALID_IN db '/abcdefghijklmnopqrstuvwxyz,;=',9
VALID_OUT db '\ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
VALID_NUM equ $ - VALID_OUT + 1
ERR_HEAD db 10,13,'RENDIR Error - $'
BAD_VERSION db 'Must be PC-DOS 3.0 or Higher$'
NO_PARMS db 'Correct Syntax is:',13,10,10
db 'RENDIR [D:][Source_Path]Source_Name[.Ext] '
db 'Target_Name[.Ext]$'
NO_TARGET db 'No Target Name Specified$'
BAD_TARGET db 'Invalid "\" or ":" in Target Name$'
DIR_NOT_FOUND db 'Source Directory Not Found$'
NOT_DIRECTORY db 'Source File Not a Directory$'
PATH_NOT_FOUND db 'Source or Target Path Not Found$'
ACCESS_DENIED db 'Access to Target Denied or Target Exists$'
PC_DOS_2_PATCH db 13,10,'or $'
DRIVES_CONFLICT db 'Source and Target Disk Drives Conflict$'
UNDEFINED_ERR db 'Undefined Error: PC-DOS Function 56H$'
ERR_TAIL db 10,10,13,' . . . Aborting',10,13,13,'$'
GOOD_MSG1 db 10,13,'Directory "$'
GOOD_MSG2 db '" . . renamed to . . "$'
GOOD_MSG3 db '"$'
END_LINE db 10,13,'$'
CODE_START: ; Processing logic starts here
mov dx,offset COPYRIGHT ; Display copyright notice
mov ah,9h ; Request display string
int 21h ; Call PC-DOS
mov ah,30h ; Request PC-DOS version
int 21h ; Call PC-DOS
cmp al,3 ; Must be 3.0 or higher
jae VERSION_OK ; If it is, keep going
mov dx,offset BAD_VERSION ; Otherwise, exit with error
jmp ERROR_EXIT
VERSION_OK: ; Parse command line into source name and target name
mov si,80h ; PSP parameter byte count pointer
mov cl,[si] ; Move byte count to CL
xor ch,ch ; Zero CH
jcxz PARMS_NO_GOOD ; If CX is zero, there are no parameters
mov dx,cx ; Save byte count in dx
inc si ; Point to parameter area
mov di,si ; Copy SI to DI for cleanup routine
cld ; Set direction flag to forward
CLEAN_PARMS: ; Change valid delimiters to blanks, lower to upper case
lodsb ; Load each character to AL
push di ; Save DI on stack
mov di,offset VALID_IN ; Point to table of valid inputs
push cx ; Save CX on stack
mov cx,VALID_NUM ; Set CX to number of inputs to look for
repne scasb ; See if any are in AL
jcxz CLEAN_END ; If not, change nothing
mov bx,VALID_NUM ; Set up BX to point to valid output
sub bx,cx ; This will leave BX one off
mov al,VALID_OUT [bx - 1] ; Load the valid output to AL
CLEAN_END:
pop cx ; Restore CX
pop di ; Restore DI
stosb ; Store modified AL back to PSP
loop CLEAN_PARMS ; Loop until CX is zero
mov cx,dx ; Restore number of bytes in PSP to CX
mov dx,2 ; Set DX to look for up to 2 parameters
mov bx,offset SOURCE_NAME ; Set BX to address of 1st parameter
mov al,' ' ; Set up to scan for first non-blank
mov di,81h ; Set DI to PC-DOS parameter pointer
FIND_PARMS: ; Start looking for parameters, load to program storage
repe scasb ; Scan while blanks
mov si,di ; Set SI to second non-blank byte
dec si ; Adjust it to first non-blank byte
inc cx ; Adjust CX to compensate
jcxz PARMS_LOADED ; If CX is zero, no parameters left
mov di,bx ; Set DI to parameter hold area
mov ax,cx ; Store CX to first byte of hold area
stosb ; DI is adjusted to second byte here
STORE: lodsb ; Load each byte to AL
cmp al,' ' ; Is it a blank?
jz END_STORE ; Yes, end of this parameter
stosb ; No, store the byte to hold area
END_STORE:
loopnz STORE ; Keep looking
sub [bx],cx ; Store number of bytes in each
jcxz PARMS_LOADED ; If CX is zero, no more parameters
dec byte ptr [bx] ; parameter to first byte of hold area
mov di,si ; Set up to scan for next non-blank
dec di ; Adjust DI to point to the blank
inc cx ; Adjust CX to compensate
dec dx ; Decrement DX counter
cmp dx,0 ; Is DX zero?
jz PARMS_LOADED ; Yes, all expected parameters loaded
add bx,PATH_FILE_LEN ; No, point to next part of hold area
jmp FIND_PARMS ; Go back and look for more
PARMS_LOADED: ; All parameters are loaded
cmp SOURCE_NAME[0],0 ; If there are no bytes in the
je PARMS_NO_GOOD ; SOURCE_NAME, no parameters present
cmp TARGET_NAME[0],0 ; Same for TARGET_NAME
ja CHECK_PARMS
PARMS_NO_GOOD: ; Exit with an error if there
mov dx,offset NO_PARMS ; are no or incorrect parameters passed
jmp ERROR_EXIT
CHECK_PARMS: ; Check for '\' or ':' in target name
mov di,TARGET_END ; Point DI to end of parameter area
mov si,offset TARGET_NAME ; Point SI to number of bytes area
lodsb ; Load number of bytes to AL
xor ah,ah ; Zero AH
mov cx,ax ; Move to CX for loop
push cx ; Save CX on stack
add si,cx ; Adjust SI to end of target name
dec si ;
std ; Set direction flag to reverse
MOVE_TARGET: ; Move target to end of area while
lodsb ; checking for '\'
cmp al,'\'
je BAD_TARGET_FOUND ; If found, target is bad
cmp al,':'
je BAD_TARGET_FOUND
stosb ; Store byte to end of area
loop MOVE_TARGET ; Keep looking
add di,1 ; Adjust DI
push di ; Save DI on stack
jmp FIND_SOURCE_DIR ; Go process source name
BAD_TARGET_FOUND: ; Exit with error if target
mov dx,offset BAD_TARGET ; contains a '\'
jmp ERROR_EXIT
FIND_SOURCE_DIR: ; Look for end of path name in source
mov si,offset SOURCE_NAME ; Point SI to number of bytes
lodsb ; Load number of bytes to AL
xor ah,ah ; Zero AH
mov di,si ; Move SI to DI for scan
mov cx,ax ; Move AX to CX for scan repeat
add di,cx ; Adjust DI to end of source name
dec di ;
mov al,'\' ; Scan for '\'
repnz scasb
cld ; Set direction flag to forward
jnz NO_DIR ; Directory is in current directory
dec cx ; Adjust CX
mov di,offset TARGET_NAME + 1 ; Point DI to target name
mov si,offset SOURCE_NAME + 1 ; Point SI to source name
rep movsb ; Move path name to target name
jmp MOVE_NAME ; DI points to position for target name
NO_DIR: ; No path, point to beginning of name
cmp SOURCE_NAME[2],':' ; Check for disk drive specification
jne NO_DISK
mov di,offset TARGET_NAME + 1 ; Point DI to target name
mov si,offset SOURCE_NAME + 1 ; Point SI to source name
mov cx,2 ; Move the two bytes into target name
rep movsb ; that contain disk drive specification
jmp MOVE_NAME
NO_DISK:
mov di,offset TARGET_NAME + 1
MOVE_NAME: ; Move target name to correct position
pop si ; Restore saved DI in SI
pop cx ; Restore CX
rep movsb
mov al,0 ; Finish ASCIIZ string with a binary 0
stosb
FIND_DIRECTORY: ; Does source directory exist?
mov dx,offset SOURCE_NAME+1 ; DX points to SOURCE_NAME
mov ah,4eh ; Request find file
mov cx,10h ; Set attribute for directories
int 21h ; Call PC-DOS
jnc FOUND_FILE ; If no error, a file was found
jmp NO_DIRECTORY
FOUND_FILE:
mov si,95h ; Position of attribute byte in DTA
lodsb ; Load attribute byte to AL
and al,10h ; Check to see if it's a directory
jnz RENAME_DIRECTORY ; If not zero, it's a directory
mov dx,offset NOT_DIRECTORY
jmp ERROR_EXIT
NO_DIRECTORY: ; Exit with error if no directory
mov dx,offset DIR_NOT_FOUND ; If file not found, exit
jmp ERROR_EXIT ; program with error message
RENAME_DIRECTORY:
mov dx,offset SOURCE_NAME + 1 ; DX points to old file name
mov di,offset TARGET_NAME + 1 ; DI points to new file name
mov ah,56h ; Request rename file
int 21h ; Call PC-DOS
jnc GOOD_RENDIR ; If no error, call was successful
cmp ax,3 ; Check for error 3 (path not found)
jne ERR_5
mov dx,offset PATH_NOT_FOUND
jmp ERROR_EXIT ; Exit program with error message
ERR_5: cmp ax,5 ; Check for error 5 (file inaccessible)
jne ERR_17
mov dx,offset ACCESS_DENIED
jmp ERROR_EXIT
ERR_17: cmp ax,17 ; Check for error 17 (drive conflict)
jne UNDEF
mov dx,offset DRIVES_CONFLICT
jmp ERROR_EXIT ; Exit program with error message
UNDEF: mov dx,offset UNDEFINED_ERR ; Undefined error from function 56H
jmp ERROR_EXIT ; Exit program with error message
GOOD_RENDIR: ; Exit with message
mov ah,9h ; Request display string
mov dx,offset GOOD_MSG1 ; Display GOOD_MSG1
int 21h ; Call PC-DOS
mov cx,2 ; 2 fields - source & target file
mov bx,offset SOURCE_NAME + 1 ; Point to source file
START1: mov si,bx ; Copy BX to SI
START2: lodsb ; Load each byte to AL
cmp al,0 ; If ASCII 0, end of field
je BETWEEN
mov dl,al ; Copy byte to DL for funciton 2H
mov ah,2h ; Request display one byte
int 21h ; Call PC-DOS
jmp START2 ; Get next character
BETWEEN:cmp cx,2 ; Is it first or second field?
jne CR_LF ; If second, display end of message
mov ah,9h ; Request display string
mov dx,offset GOOD_MSG2 ; Display GOOD_MSG2
int 21h ; Call PC-DOS
jmp NEXT ; Go process next field
CR_LF: mov ah,9h ; Request display string
mov dx,offset GOOD_MSG3 ; Display GOOD_MSG3
int 21h ; Call PC-DOS
mov dx,offset END_LINE ; Terminate display line
mov ah,9h ; Request display string
int 21h ; Call PC-DOS
NEXT: add bx,PATH_FILE_LEN ; Move BX to point to next field
loop START1 ; Loop for second field
jmp EXIT ; Exit RENDIR
ERROR_EXIT: ; Print Error Message and Exit
push dx ; Save error message pointer on stack
mov ah,9h ; Request display string
mov dx,offset ERR_HEAD ; Display error header
int 21h ; Call PC-DOS
pop dx ; Display error message
int 21h ; Call PC-DOS
mov dx,offset ERR_TAIL ; Display error tail
int 21h ; Call PC-DOS
EXIT: int 20h ; Exit to PC-DOS
RENDIR ends
end BEGIN